﻿#define _CRT_SECURE_NO_WARNINGS 1


#include<iostream>
//
using namespace std;
//
class Date
{
public:
	Date(int year = 2025, int month = 1, int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{ }

	~Date()
	{
		cout << "~Date()" << endl;
	}

	int _year;
	int _month;
	int _day;
};
//
//int main()
//{
//	auto_ptr<Date> ap1(new Date);
//	// 拷⻉时，管理权限转移，被拷⻉对象ap1悬空
//	auto_ptr<Date> ap2(ap1);
//	// 空指针访问，ap1对象已经悬空
//	//ap1->_year++;
//
//	unique_ptr<Date> up1(new Date);
//	// 不⽀持拷⻉
//	//unique_ptr<Date> up2(up1);
//	// ⽀持移动，但是移动后up1也悬空，所以使⽤移动要谨慎
//	unique_ptr<Date> up3(move(up1));
//
//	shared_ptr<Date> sp1(new Date);
//	// ⽀持拷⻉
//	shared_ptr<Date> sp2(sp1);
//	shared_ptr<Date> sp3(sp2);
//
//	cout << sp1.use_count() << endl;
//	sp1->_year++;
//	cout << sp1->_year << endl;
//	cout << sp2->_year << endl;
//	cout << sp3->_year << endl;
//
//	// ⽀持移动，但是移动后sp1也悬空，所以使⽤移动要谨慎
//	shared_ptr<Date> sp4(move(sp1));
//
//	return 0;
//}

template<class T>
void DeleteArrayFunc(T* ptr)
{
	delete[] ptr;
}

template<class T>
struct DeleteArray
{
	void operator()(T* ptr)
	{
		delete[] ptr;
	}
};

//int main()
//{
//	// 这样实现程序会崩溃
//	//unique_ptr<Date> up1(new Date[10]);
//	//shared_ptr<Date> sp1(new Date[10]);
//
//	// 解决⽅案1
//	// 因为new[]经常使⽤，所以unique_ptr和shared_ptr
//	// 实现了⼀个特化版本，这个特化版本析构时⽤的delete[]
//	unique_ptr<Date[]> up1(new Date[5]);
//	shared_ptr<Date[]> sp1(new Date[5]);
//
//	// 解决⽅案2
//	// 仿函数对象做删除器
//	// unique_ptr<Date, DeleteArray<Date>> up2(new Date[5], DeleteArray<Date>());
//	// unique_ptr和shared_ptr⽀持删除器的⽅式有所不同
//	// unique_ptr是在类模板参数⽀持的，shared_ptr是构造函数参数⽀持的
//	// 使⽤仿函数unique_ptr可以不在构造函数传递，因为仿函数类型构造的对象直接就可以调⽤
//	unique_ptr<Date, DeleteArray<Date>> up2(new Date[5]);
//	shared_ptr<Date> sp2(new Date[5], DeleteArray<Date>());
//
//	// 函数指针做删除器
//	unique_ptr<Date, void(*)(Date*)> up3(new Date[5], DeleteArrayFunc<Date>);
//	shared_ptr<Date> sp3(new Date[5], DeleteArrayFunc<Date>);
//
//	return 0;
//}


int main()
{
	shared_ptr<Date> sp1(new Date(2024, 9, 11));

	shared_ptr<Date> sp2 = make_shared<Date>(2024, 9, 11);

	auto sp3 = make_shared<Date>(2024, 9, 11);

	shared_ptr<Date> sp4;

	// if (sp1.operator bool())
	if (sp1)
	{
		cout << "sp1 is not nullptr" << endl;
	}

	if (!sp4)
	{
		cout << "sp1 is nullptr" << endl;
	}

	// 报错
	//shared_ptr<Date> sp5 = new Date(2024, 9, 11);
	//unique_ptr<Date> sp6 = new Date(2024, 9, 11);

	return 0;
}